
package cn.spdb.harrier.server.worker.exec;

import java.time.LocalDateTime;
import java.util.Date;

import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;

import cn.spdb.harrier.common.Constants;
import cn.spdb.harrier.common.enmus.ExecutionStatus;
import cn.spdb.harrier.common.utils.DateUtils;
import cn.spdb.harrier.common.utils.PropertyUtils;
import cn.spdb.harrier.common.utils.Symbol;
import cn.spdb.harrier.dao.entity.UdsJobStepRecord;
import cn.spdb.harrier.dao.utils.BeanContext;
import cn.spdb.harrier.server.entity.JobStepBean;
import cn.spdb.harrier.server.utils.ResourceDownUtils;
import cn.spdb.harrier.server.worker.task.TaskManager;

public class TaskExecuteRunnable extends ExecuteRunable {

/**
 * 任务执行线程的入口方法。
 *
 * <p>该方法负责：
 * <ul>
 *   <li>初始化任务上下文</li>
 *   <li>遍历并执行每个任务步骤（JobStep）</li>
 *   <li>记录每一步的执行日志和状态</li>
 *   <li>处理任务中断、资源下载失败等情况</li>
 *   <li>最终更新任务状态并清理资源</li>
 * </ul>
 */
@Override
public void run() {
    try {
        // 初始化全局参数
        jobExecutionContext.initGlobal();
        // 设置任务开始时间
        jobExecutionContext.setStartTime(new Date());

        // 如果当前状态不是 STEP_RUNNING，则设置为运行中状态
        if (jobExecutionContext.getExecutionStatus() != ExecutionStatus.STEP_RUNNING) {
            jobExecutionContext.setExecutionStatus(ExecutionStatus.STEP_RUNNING);
        }

        // 记录任务开始日志，打印任务实例 ID
        logger.info("the task begins to execute. task instance id: {}", jobExecutionContext.getTaskInstanceId());

        // 遍历任务的所有步骤（按顺序）
        for (JobStepBean stepBean : jobExecutionContext.getJobStepListSort()) {

            // 重置环境变量和参数，继承全局变量
            stepBean.resetEnvs(jobExecutionContext.getGloEnvs());
            stepBean.resetPararmeter(jobExecutionContext.getGloParams());

            // 设置当前步骤的开始时间
            stepBean.setStartTime(LocalDateTime.now());

            // 构建当前步骤的数据库记录对象 UdsJobStepRecord
            UdsJobStepRecord record = buildUdsJobStepRecord(
                    jobExecutionContext.getTaskInstanceId(),
                    jobExecutionContext.getUdsJob(), stepBean);

            // 生成唯一 ID 作为步骤记录主键
            record.setId(workerManagerThread.getSingleId());

            // 如果未设置日志路径，则根据规则构造默认日志路径
            if (StringUtils.isBlank(stepBean.getLogPath())) {
                String log = workerManagerThread.getWorkerConfig().getLogStepPrex()
                        + DateUtils.format(new Date(), DateUtils.PATTERN_YYYYMMDD_CONS)
                        + Symbol.XIE_XIAN
                        + record.getPlatform() + Symbol.XIE_XIAN
                        + record.getSystems() + Symbol.XIE_XIAN
                        + record.getJob() + Symbol.XIE_XIAN
                        + record.getNumTimes() + Symbol.XIA_HUA_XIAN
                        + record.getStepNum() + Symbol.XIA_HUA_XIAN
                        + record.getId() + ".log";

                // 设置步骤日志路径
                stepBean.setLogPath(log);
            }

            // 将日志路径写入记录
            record.setLogPath(stepBean.getLogUri().toString());

            // 插入步骤执行记录到数据库
            workerManagerThread.insertUdsJobStepRecord(record);

            try {
                // 创建当前步骤的任务处理器
                nowTask = TaskManager.newTask(stepBean);

                // 检查是否被取消，如果被取消则标记为 KILL 状态并终止
                if (cancel.get()) {
                    stepBean.setExitId(Constants.EXIT_CODE_KILL);
                    nowTask.getLogger().error("job step is kill, end");
                    break;
                }

                // 下载任务所需资源（如脚本、文件等）
                if (!ResourceDownUtils.downloadResource(stepBean)) {
                    nowTask.getLogger().error("download resource is error: {}",
                            stepBean.getStepUri().toString());
                }

                // 初始化任务处理器
                nowTask.init();

                // 执行任务主体逻辑
                nowTask.handle();

                // 后置处理（例如清理、上传结果等）
                nowTask.after();

                // 如果当前步骤执行失败，跳出循环，不再继续后续步骤
                if (nowTask.getExitStatus() != ExecutionStatus.SUCCESS) {
                    break;
                }
            } catch (Exception e) {
                // 异常捕获并打印堆栈信息
                e.printStackTrace();
                break;
            } finally {
                // 设置步骤结束时间
                record.setEndTime(LocalDateTime.now());

                // 设置返回码（退出状态）
                record.setReturnCode(stepBean.getExitId());

                // 更新步骤执行记录到数据库
                workerManagerThread.updateJobStepRecord(record);
            }
        }
    } catch (IllegalArgumentException e) {
        // 捕获非法参数异常并打印堆栈信息
        e.printStackTrace();
    } finally {
        // 根据执行情况设置最终任务状态
        jobExecutionContext.setExecutionStatus(
                ObjectUtils.isEmpty(nowTask) ? ExecutionStatus.FAILURE : nowTask.getExitStatus());

        // 设置任务结束时间
        jobExecutionContext.setEndTime(new Date());

        // 通知 WorkerManager 更新任务完成状态
        workerManagerThread.updatejobDone(jobExecutionContext);

        // 减少主机上的任务计数器（释放资源）
        workerManagerThread.decrementJob(jobExecutionContext);
    }
}

}
